package com.pulaien.web.controller.fundmanagement;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pulaien.common.core.controller.BaseController;
import com.pulaien.common.core.domain.AjaxResult;
import com.pulaien.common.core.domain.R;
import com.pulaien.common.core.domain.entity.SysUser;
import com.pulaien.common.core.page.TableDataInfo;
import com.pulaien.common.domain.ResponseCode;
import com.pulaien.common.utils.ConstantsUtil;
import com.pulaien.common.utils.MessageUtils;
import com.pulaien.common.utils.date.DateUtils;
import com.pulaien.common.utils.date.EnumDateStyle;
import com.pulaien.system.domain.Customer;
import com.pulaien.system.domain.CustomerPaymentInfo;
import com.pulaien.system.domain.Recharge;
import com.pulaien.system.domain.dto.fundmanagement.ExtRecharge;
import com.pulaien.system.domain.dto.fundmanagement.ExtRechargeDto;
import com.pulaien.system.domain.dto.fundmanagement.PayRecordExportParam;
import com.pulaien.system.domain.dto.fundmanagement.PaymentInfoVo;
import com.pulaien.system.mapper.CustomerMapper;
import com.pulaien.system.mapper.CustomerPaymentInfoMapper;
import com.pulaien.system.mapper.RechargeMapper;
import com.pulaien.system.service.ICustomerService;
import com.pulaien.system.service.IExchangeRateService;
import com.pulaien.system.service.SequenceUtil;
import com.pulaien.system.service.customersetup.AdminUserService;
import com.pulaien.system.service.fundmanagement.PayRecordService;
import com.spire.xls.FileFormat;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;

/**
 * 充值记录管理Controller
 */
@RestController
@Api(tags = "买家端-账户充值", description = "买家端-账户充值")
@RequestMapping("/shop/payRecord")
public class PayRecordController extends BaseController {


    private final PayRecordService payRecordService;
    private final AdminUserService adminUserService;
    private final CustomerPaymentInfoMapper customerPaymentInfoMapper;
    private final ICustomerService customerService;
    private final RechargeMapper rechargeMapper;
    private final CustomerMapper customerMapper;

    @Resource
    private IExchangeRateService exchangeRateService;


    public PayRecordController(
            PayRecordService payRecordService,
            AdminUserService adminUserService,
            CustomerPaymentInfoMapper customerPaymentInfoMapper,
            ICustomerService customerService,
            RechargeMapper rechargeMapper,
            CustomerMapper customerMapper
    ) {
        this.payRecordService = payRecordService;
        this.adminUserService = adminUserService;
        this.customerPaymentInfoMapper = customerPaymentInfoMapper;
        this.customerService = customerService;
        this.rechargeMapper = rechargeMapper;
        this.customerMapper = customerMapper;
    }


    @ApiOperation("充值记录列表分页展示")
    @GetMapping(value = "/list")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "当前记录起始索引", paramType = "query", defaultValue = "1", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize", value = "每页显示记录数", paramType = "query", defaultValue = "10", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "orderByColumn", value = "排序列", paramType = "query"),
            @ApiImplicitParam(name = "isAsc", value = "排序的方向 \"desc\" 或者 \"asc\"", paramType = "query"),
            @ApiImplicitParam(name = "reasonable", value = "分页参数合理化", paramType = "query", dataType = "Boolean")
    })
    public TableDataInfo list(
            ExtRecharge message
    ) {
        startPage();
        List<Recharge> record = payRecordService.list(message);
        return getDataTable(record);
    }


    @ApiOperation("查询统计数量")
    @GetMapping(value = "/getStatisticalNum")
    public R<JSONObject> getStatisticalNum(ExtRecharge message) {
        return R.ok(payRecordService.getStatisticalNum(message));
    }


    /**
     * @param totalPrice
     * @return totalPrice  充值的金额
     * price       换算的日元金额
     */
    @ApiOperation("paypal充值")
    @RequestMapping(value = "/pay", method = RequestMethod.GET)
    @ResponseBody
    public AjaxResult pay(
            @RequestParam BigDecimal totalPrice,
            @RequestParam BigDecimal inRate,
            @RequestParam Long inPrice,
            @RequestParam(value = "clientType" , defaultValue = "0" , required = false) Integer clientType
    ) {


        //获取日元汇率
        /*ExchangeRate exchangeRate = exchangeRateService.queryJpyExchangeRate();
        BigDecimal rate = BigDecimal.ZERO;
        if (exchangeRate != null) {
            rate = exchangeRate.getExchangeRate();
        }*/


        com.alibaba.fastjson2.JSONObject latestRate = exchangeRateService.getRate();
        BigDecimal rate = (BigDecimal)latestRate.get("rate");



        //订单总价换算日元（向上取整一位）
        BigDecimal price = totalPrice.multiply(rate).setScale(0, BigDecimal.ROUND_UP);


        if(inRate.compareTo(rate) != 0) {
            return AjaxResult.error(MessageUtils.getMessage(10308));
        }

        long l = inPrice.longValue();
        long l1 = Long.valueOf(price.toString()).longValue();
        if(l != l1) {
            return AjaxResult.error(MessageUtils.getMessage(10309));
        }

        String safeSeqNo = SequenceUtil.getSafeSeqNo(ConstantsUtil.CM_RECHARGE_NO_KEY_NAME, ConstantsUtil.CM_RECHARGE_NO_PREFIX, ConstantsUtil.CM_RECHARGE_NO_NUM);
        //return payRecordService.pay(safeSeqNo, totalPrice, price, rate);
        return payRecordService.payPCAndH5(safeSeqNo, totalPrice, price, rate , clientType);
    }


    /**
     * PayPal 支付成功 回调
     *
     * @param paymentNumber 后台生成平台支付流水号
     * @param paymentId
     * @param payerId       paypal返回支付ID
     * @param moneyJpy      充值日元
     * @param money         充值人民币金额
     * @param payTime       充值时间
     */
    @ApiOperation("paypal回调")
    @GetMapping("/payPalSuccess")
    public AjaxResult payPalSuccess(
            @RequestParam("paymentNumber") String paymentNumber,
            @RequestParam("paymentId") String paymentId,
            @RequestParam("PayerID") String payerId,
            @RequestParam("moneyJpy") BigDecimal moneyJpy,
            @RequestParam("money") BigDecimal money,
            @RequestParam(value = "rate") BigDecimal exchangeRate,
            @RequestParam("payTime") String payTime


    ) {

        //return payRecordService.payPalSuccess(paymentNumber, paymentId, payerId, money);
        return payRecordService.payPalSuccessPCAndH5(paymentNumber, paymentId, payerId, money , exchangeRate , moneyJpy);
    }


    /**
     * paypal 回调 取消支付
     *
     * @throws IOException
     */
    @ApiOperation("paypal回调取消")
    @GetMapping("/payPalCancel")
    public AjaxResult payPalCancel(@RequestParam("paymentNumber") String paymentNumber) {
        return payRecordService.payPalCancel(paymentNumber);
    }


    @ApiOperation("保存充值表单")
    @PostMapping(value = "/saveAction")
    @Transactional
    public R<Recharge> saveAction(
            @RequestBody ExtRechargeDto recharge
    ) {

        if(null == recharge.getExchangeRate()) {
            return R.fail(MessageUtils.getMessage(10306));
        }
        if(null == recharge.getMoneyJpy()) {
            return R.fail(MessageUtils.getMessage(10307));
        }

        //后台获取汇率
        com.alibaba.fastjson2.JSONObject latestRate = exchangeRateService.getRate();
        BigDecimal rate = (BigDecimal)latestRate.get("rate");
        if(rate.compareTo(recharge.getExchangeRate()) != 0) {
            return R.fail(MessageUtils.getMessage(10308));
        }


        BigDecimal bigDecimal = recharge.getMoney().multiply(rate).setScale(0, BigDecimal.ROUND_UP);
        if(bigDecimal.compareTo(recharge.getMoneyJpy()) != 0) {
            return R.fail(MessageUtils.getMessage(10309));
        }


        SysUser currentUser = this.adminUserService.getCurrentUser().getUser();

        recharge.setCustomerName(currentUser.getUserName());
        recharge.setCustomerId(currentUser.getUserId());
        recharge.setRechargeNo(SequenceUtil.getSafeSeqNo(
                ConstantsUtil.CM_RECHARGE_NO_KEY_NAME, ConstantsUtil.CM_RECHARGE_NO_PREFIX, ConstantsUtil.CM_RECHARGE_NO_NUM));
        recharge.setTradingNo(SequenceUtil.getSafeSeqNo(
                ConstantsUtil.CM_RECHARGE_NO_KEY_NAME, ConstantsUtil.CM_TRADING_NO_PREFIX, ConstantsUtil.CM_TRADING_NO_NUM));
        //是否开启保存支付信息 0关闭 1开启
        /*String paymentInfoFlag = recharge.getPaymentInfoFlag();
        if (StringUtils.equals(paymentInfoFlag, ConstantsUtil.PAYMENT_INFO_FLAG_YES)) {

            QueryWrapper queryExample = new QueryWrapper<>();
            queryExample.eq("user_id", currentUser.getUserId());
            queryExample.eq("recharge_type", recharge.getRechargeType());
            queryExample.eq("del_flag", ConstantsUtil.FLG_NORMAL);
            List<CustomerPaymentInfo> paymentInfoList = customerPaymentInfoMapper.selectList(queryExample);

            if (paymentInfoList != null && paymentInfoList.size() > 0) {
                //存在 则更新
                CustomerPaymentInfo paymentInfo = paymentInfoList.get(0);
                paymentInfo.setBankNo(recharge.getBankNo());
                paymentInfo.setBankName(recharge.getBankName());
                paymentInfo.setDrawee(recharge.getDrawee());
                customerPaymentInfoMapper.updateById(paymentInfo);

            } else {
                //不存在 新增
                CustomerPaymentInfo paymentInfo = new CustomerPaymentInfo();
                paymentInfo.setUserId(currentUser.getUserId());
                paymentInfo.setUserName(currentUser.getUserName());
                paymentInfo.setBankNo(recharge.getBankNo());
                paymentInfo.setBankName(recharge.getBankName());
                paymentInfo.setDrawee(recharge.getDrawee());
                paymentInfo.setDelFlag(ConstantsUtil.FLG_NORMAL);
                paymentInfo.setRechargeType(recharge.getRechargeType());
                customerPaymentInfoMapper.insert(paymentInfo);
            }
        } else {

            QueryWrapper updateInfoExample = new QueryWrapper();
            CustomerPaymentInfo info = new CustomerPaymentInfo();
            info.setDelFlag(ConstantsUtil.FLG_DELETE);
            updateInfoExample.eq("User_id", currentUser.getUserId());
            updateInfoExample.eq("del_flag", ConstantsUtil.FLG_NORMAL);
            customerPaymentInfoMapper.update(info, updateInfoExample);

        }
        //更新客户信息
        if (paymentInfoFlag != null) {
            Customer updateCustomer = new Customer();
            updateCustomer.setPaymentInfoFlag(paymentInfoFlag);

            QueryWrapper updateCustomerExample = new QueryWrapper();
            updateCustomerExample.eq("user_id", currentUser.getUserId());
            updateCustomerExample.eq("del_flag", ConstantsUtil.FLG_NORMAL);
            customerMapper.update(updateCustomer, updateCustomerExample);
        }*/


        Recharge oytqcRecharge = payRecordService.insertRecord(recharge);
        return R.ok(oytqcRecharge);
    }


    @ApiOperation("修改状态")
    @PostMapping(value = "/updateAction")
    public R<String> updateAction(@RequestBody ExtRechargeDto recharge) {
        return payRecordService.updateForNew(recharge);
    }


    @ApiOperation("查询付款信息")
    @GetMapping(value = "/queryPaymentInfo")
    public R<PaymentInfoVo> queryPaymentInfo() {
        PaymentInfoVo vo = new PaymentInfoVo();
        SysUser currentUser = adminUserService.getCurrentUser().getUser();
        //是否开启保存支付信息
        Customer extCustomer = new Customer();
        extCustomer.setUserId(currentUser.getUserId());
        Customer customer = this.customerService.customerData(extCustomer);
        if (StringUtils.equals(ConstantsUtil.PAYMENT_INFO_FLAG_YES, customer.getPaymentInfoFlag())) {

            QueryWrapper paymentInfoExample = new QueryWrapper();
            paymentInfoExample.eq("user_id", currentUser.getUserId());
            paymentInfoExample.eq("del_flag", ConstantsUtil.FLG_NORMAL);
            List<CustomerPaymentInfo> paymentInfoList = customerPaymentInfoMapper.selectList(paymentInfoExample);

            if (paymentInfoList != null && paymentInfoList.size() > 0) {
                CustomerPaymentInfo paymentInfo = paymentInfoList.get(0);
                BeanUtils.copyProperties(paymentInfo, vo);
            }
            vo.setPaymentInfoFlag(ConstantsUtil.PAYMENT_INFO_FLAG_YES);

        } else {
            vo.setPaymentInfoFlag(ConstantsUtil.PAYMENT_INFO_FLAG_NO);
        }
        return R.ok(vo);
    }


    @ApiOperation("查询凭证姓名")
    @PostMapping(value = "/queryRealName")
    public R<String> queryRealName() {
        SysUser user = adminUserService.getCurrentUser().getUser();
        Customer extCustomer = new Customer();
        extCustomer.setUserId(user.getUserId());
        Customer customer = this.customerService.customerData(extCustomer);
        if (customer == null) {
            return R.fail(MessageUtils.getMessage(ResponseCode.GET_NOT_INFORMATION_FAIL));
        }
        return R.ok(customer.getRealName());
    }


    @ApiOperation("导出御请求书")
    @PostMapping(value = "/pdf")
    public void pdf(
            HttpServletResponse response,
            @RequestBody PayRecordExportParam param
    ) throws Exception {
        Integer id = param.getId();
        String realName = param.getRealName();
        Recharge recharge = rechargeMapper.selectById(id);
        if (recharge == null) {
            return;
        }
        //更新用户姓名
        SysUser currentUser = adminUserService.getCurrentUser().getUser();
        Customer updateCustomer = new Customer();
        updateCustomer.setRealName(realName);
        QueryWrapper updateCustomerExample = new QueryWrapper();
        updateCustomerExample.eq("user_id", currentUser.getUserId());
        updateCustomerExample.eq("del_flag", ConstantsUtil.FLG_NORMAL);
        customerMapper.update(updateCustomer, updateCustomerExample);

        String payTime = DateUtils.getDate(recharge.getPayTime());
        //String payTimeFormat = DateUtils.timeStamp2Date(Integer.valueOf(payTime), EnumDateStyle.YYYY_MM_DD_EN.getValue(), null);
        String payTimeFormat = DateUtils.timeStamp2Date(Integer.parseInt(recharge.getPayTime()), EnumDateStyle.YYYY_MM_DD_EN.getValue(), null);
        HashMap<String, Object> topMap = new HashMap<>(4);
        topMap.put("realName", realName);
        topMap.put("rechargeNo", recharge.getRechargeNo());
        topMap.put("payTime", payTimeFormat);
        topMap.put("money", recharge.getMoney());
        topMap.put("moneyJpy", recharge.getMoneyJpy());
        topMap.put("tradingNo", recharge.getTradingNo());
        topMap.put("exchangeRate", recharge.getExchangeRate().setScale(2, BigDecimal.ROUND_DOWN));

        ClassPathResource classPathResource = new ClassPathResource("excelTemplates" + File.separator + "PayRecordTemplate.xlsx");
        TemplateExportParams template = new TemplateExportParams(classPathResource.getPath(), true);

        Workbook workbook = ExcelExportUtil.exportExcel(template, topMap);
        response.setContentType("application/pdf;charset=utf-8");
        response.setHeader("Content-Disposition",
                "attachment;filename=" + URLEncoder.encode("御請求書", "utf-8") + recharge.getTradingNo() + ".pdf");
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        workbook.write(outputStream);
        ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
        com.spire.xls.Workbook workbook1 = new com.spire.xls.Workbook();
        workbook1.loadFromStream(inputStream);

        //设置字体格式，linux服务器上，要在/usr/share/fonts/ 目录下检查该字体集是否存在
        //不存在要安装宋体，否者中文乱码

        Font font = new Font("宋体", Font.PLAIN, 16);
        workbook1.createFont(font);

        //pdf 自适应屏幕大小
        workbook1.getConverterSetting().setSheetFitToWidth(true);
        workbook1.saveToStream(response.getOutputStream(), FileFormat.PDF);
    }

}
